﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using CapturarObjetos.Nucleo;

namespace CapturarObjetos.Objetos
{
    class Jogador : ObjetoJogo
    {
        public float DirecaoFrontal { get; set; }
        public float AlcanceMaximoX { get; set; }
        public float AlcanceMaximoZ { get; set; }

        public int hp; //Muahahaha

        public int aceleration;


        public bool isMoving;

        float speed;

        public int movimentos;

        public int energias_coletadas;



        public bool colidiu = false;

        public const float Velocidade = 0.75f;
        public const float VelocidadeDeCurva = 0.025f;

        public static List<Jogador> listaJogadores = new List<Jogador>();

        public Jogador(ContentManager Content, string _modelo)
            : base()
        {
            Modelo = Content.Load<Model>(_modelo);
            DirecaoFrontal = 0.0f;
            aceleration = 0;
            AlcanceMaximoX = 100;
            AlcanceMaximoZ = 100;
            hp = 5;
            energias_coletadas = 0;

            Jogador.listaJogadores.Add(this);
        }

        
        
        public void Update(GameTime gameTime, KeyboardState teclado_atual, KeyboardState teclado_anterior, MouseState mouse_anterior, MouseState mouse)
        {

            if (aceleration <= 0)
            {
                isMoving = false;
            }

            


            if (isMoving)
            {
                if (aceleration <= 0)
                {
                    isMoving = false;
                }

                else
                {
                    speed = (1.00f) + (float)(aceleration * 0.01);
                    doMove(this, speed, 0);
                    aceleration--;
                }
            }
            else
            {

                if (teclado_atual.IsKeyDown(Keys.W))
                {
                    
                    doMove(this, 1, 0);
                }

                if (teclado_atual.IsKeyDown(Keys.S))
                {
                    doMove(this, -1, 0);
                }


                if (teclado_atual.IsKeyDown(Keys.A))
                {
                    doMove(this, 0, 1);
                }

                else if (teclado_atual.IsKeyDown(Keys.D))
                {
                    doMove(this, 0, -1);
                }

            }

            if (mouse_anterior.LeftButton == ButtonState.Pressed && mouse.LeftButton == ButtonState.Released)
            {
                this.aceleration = (Power_Bar.power * 10) + 1;
                Power_Bar.visible = false;
                Power_Bar.power = 0;
                isMoving = true;
                this.movimentos++;


            }
            
            
                        
        }

        private bool ManterNoTabuleiro(Vector3 posicaoFutura)
        {
            if ((Math.Abs(posicaoFutura.X) > AlcanceMaximoX) ||
                (Math.Abs(posicaoFutura.Z) > AlcanceMaximoZ))
                return false;
            return true;
        }


        public Boolean canMove()
        {
            if ((Math.Abs(this.Posicao.X) > AlcanceMaximoX))
            {
                return false;
            }

            if ((Math.Abs(this.Posicao.X) < 0))
            {
                return false;
            }

            if ((Math.Abs(this.Posicao.Z) > AlcanceMaximoZ))
            {
                return false;
            }

            if ((Math.Abs(this.Posicao.Z) < 0))
            {
                return false;
            }


            return true;
        }




      
        /// <summary>
        /// Move o jogador
        /// </summary>
        /// <param name="jogador"> Jogador que vai se mover </param>
        /// <param name="speed"> Velocidade com que se move (Vai virar força) </param>
        public bool doMove(Jogador jogador, float speed, int rotation)
        {

            
            colidiu = false;

            //Posicao antiga
            Vector3 posicaoPassada = Posicao;

            //preciso testar *primeiro* se a posição futura é válida para não travar, por isso a guardo..
            Vector3 posicaoFutura = Posicao;

            //estas duas variáveis temporárias servem para o giro e o movimento
           // float quantoVirar = 0;
            Vector3 movimento = Vector3.Zero;
            movimento.Z = -speed;

            //o pra onde ele vai virar é corrigido pela velocidade de giro
            DirecaoFrontal += rotation * VelocidadeDeCurva;
            //isto está aqui apenas pq esta variável tem outro nome na hora de desenhar...
            RotacaoY = DirecaoFrontal;
            //preciso girar meu objeto naquela direção antes de andar
            Matrix matrixOrientacao = Matrix.CreateRotationY(jogador.DirecaoFrontal);
            //ando com ele aquela quantidade de movimento naquela direcao de orientacao
            Vector3 velocidade = Vector3.Transform(movimento, matrixOrientacao);
            //corrijo pela escala da velocidade
            if(speed < 0)
                velocidade *= -speed;
            else
                velocidade *= speed;
            //agora sim esta será a nova posicao do objeto
            posicaoFutura = Posicao + velocidade;


            



            //Andou!
            Posicao = posicaoFutura;

            this.Update();



            //Checagem colisão
            foreach (Barreira objeto in Barreira.listaBarreiras)
            {

                if (objeto.CaixaColisao.Intersects(this.CaixaColisao) && objeto.Ativo)
                {
                    if (jogador.Ativo && objeto.Ativo)
                    colidiu = true; 
                }

            }


            //Checagem colisão com energias
            foreach (Energia objeto in Energia.listaEnergias)
            {

                if (objeto.CaixaColisao.Intersects(this.CaixaColisao) && objeto.Ativo)
                {
                    if (jogador.Ativo && objeto.Ativo)
                    {
                        objeto.Ativo = false;
                        energias_coletadas++;
                    }
                }

            }


            if (colidiu)
            {
                Posicao = posicaoPassada;
                aceleration = 0;
                hp--;
            }

            if(!canMove())
            {
                aceleration = 0;
                Posicao = posicaoPassada;
            }

            speed--;

            if (speed > 0)
            {
                return doMove(jogador, speed, rotation);
                
            }
            else
            {
                return true;
            }

            

        }

        

    }
}
